<template>
  <div class="display-flex">
    <div class="flex-1">
      <div v-if="pages.length">
        <EditorHeader
          v-if="curWidget"
          :editor-type="editorType"
          :src-widget="curWidget"
          class="editor-opt-header"
          @createGroup="createGroup"
          @widgetAutoLayout="widgetAutoLayout"></EditorHeader>
        <div class="editor-workspace">
          <div
            v-for="page in pages" :key="page.id"
            v-if="page.id === pageHdl.activePage.id"
            :style="{width: `${page.rect.width}px`, height: `${page.rect.height}px`,transform: `scale(${scaleValue})`}"
            class="pad-window">
            <Widget :id="page.id" :widget="page" :is-multi-mode="showSelectionBox"></Widget>
            <WidgetSelectionBox v-model="selectionBoxRect" :show-box="showSelectionBox"></WidgetSelectionBox>
            <!--<div v-show="isWidgetScaling" v-loading="true" class="position-full"></div>-->
          </div>
        </div>
      </div>
      <EmptyContent v-else empty-text="暂无数据，请切换房间配置"></EmptyContent>
    </div>
    <div
      v-if="curWidget"
      class="editor-attribute-side"
      :style="{'width': showAttrDock ? '300px' : '0px'}">
      <i
        class="iconfont font-size-24 side-collapse-icon"
        :class="showAttrDock ? 'icon-double-arro-right' : 'icon-double-arrow-left'"
        @click="showAttrDock = !showAttrDock"></i>
      <EditorDock
        :editor-type="editorType"
        :widget="curWidget"
        :style="{'display': showAttrDock ? 'block' : 'none'}"></EditorDock>
    </div>
    <el-dialog
      title="引用列表"
      :visible.sync="citeListDialog"
      :close-on-click-modal="false"
      width="500px"
      center>
      <CiteList
        :relatedComponents="relatedComponents"
        :curWidget="curWidget"
        :relatedLogic="relatedLogic"
        @jumpComponents="jumpComponents"
        @jumpLogic="jumpLogic"></CiteList>
    </el-dialog>
    <WidgetSelectPage></WidgetSelectPage>
    <div class="slider-block">
      <el-slider
        v-model="scaleValue"
        :min="0"
        :max="2"
        :step="0.1"
        vertical
        height="100px">
      </el-slider>
    </div>
    <!--关联设备-->
    <el-dialog
      title="关联设备"
      :visible.sync="relateDeviceDialog"
      :close-on-click-modal="false"
      width="500px"
      center
      @close="relateDeviceDialog=false">

      <RelateDevice :devices="devices" @relateDeviceCancel="relateDeviceDialog=false"
                    @relateDeviceSubmit="relateDeviceSubmit"></RelateDevice>

    </el-dialog>
  </div>
</template>

<script>
  import EditorHeader from './EditorHeader';
  import EditorDock from './EditorDock';
  import Widget from '@/components/IDE/widget/atom/Widget';
  import {mapActions, mapState} from "vuex";
  import {WidgetFactory} from "@/modules/IDE/widgetFactory";
  import {
    assembleTreeFromArray,
    deepCopy,
    downloadFileApi,
    findObjectByValue,
    getUserInfo,
    messageHandle
  } from "@/utils";
  import {userRoleCfg} from "@/config/ide/common";
  import API from "@/api";
  import EventDock from "@/page/IDE/editor/dock/EventDock.vue";
  import WidgetSelectionBox from "@/components/IDE/WidgetSelectionBox.vue";
  import WidgetSelectPage from "@/components/IDE/WidgetSelectPage.vue";
  import CiteList from "@/components/IDE/CiteList.vue";
  import RelateDevice from "@/components/IDE/RelateDevice.vue";
  import {getStorage, setStorage, StorageKey} from "@/config/sessions";
  import _ from "lodash";
  import {assetBaseUrl} from "@/config/env";
  import widget from "@/components/IDE/widget/atom/Widget.vue";

  export default {
    name: "EditorWorkspace",
    components: {
      EventDock, EditorHeader, EditorDock, Widget, WidgetSelectionBox, CiteList, WidgetSelectPage, RelateDevice
    },
    props: {
      editorType: {
        type: String,
        default: 'room', // room/component
      },
    },
    data() {
      return {
        loading: true,
        userRoleCfg: userRoleCfg,
        userInfo: getUserInfo(),
        roomId: '',
        componentId: '',
        factory: new WidgetFactory(),
        curWidget: undefined,
        copiedWidgetArr: [],
        isMultiSelectMode: false, // Ctrl 键否按下，进入多选模式
        isWidgetScaling: false,
        showAttrDock: true,
        showSelectionBox: false,
        selectionBoxRect: {top: 0, left: 0, width: 0, height: 0},
        citeListDialog: false,
        relatedComponents: [],
        relatedLogic: [],
        scaleValue: 1,
        relateDeviceDialog: false,
        devices: [],
        newDevices: [],
        deviceComponentId: ''
      };
    },
    computed: {
      ...mapState({
        activeTheme: state => state.ide.activeTheme,
        globalLogicList: state => state.ide.globalLogicList,
        curPageType: state => state.ide.curPageType,
        draggingWidget: state => state.ide.draggingWidget,
        selectWidgetIds: state => state.ide.selectWidgetIds,
        pointerPosition: state => state.ide.pointerPosition,
        curPageHandler: state => state.ide.curPageHandler,
        curSubPageHandler: state => state.ide.curSubPageHandler,
      }),
      pages() {
        const pages = [];
        this.curPageHandler.pages.forEach(page => pages.push(page));
        if (this.editorType === 'room') {
          this.curSubPageHandler.pages.forEach(page => pages.push(page));
        }
        return pages;
      },
      pageHdl() {
        switch (this.curPageType) {
          case 'page':
            return this.curPageHandler;
          case 'subPage':
            return this.curSubPageHandler;
          default:
            return null;
        }
      },
    },
    watch: {
      // 当前选中 widget 更改后，刷新所有 widget 的 active 状态
      selectWidgetIds(widgetIds = []) {
        WidgetFactory.production.forEach(widget => {
          widget.active = widgetIds.includes(widget.id);
        });
        // 先显示当前组件本身和所有父组件，当前选中的组件如果存在遮挡，这递归向上隐藏兄弟组件
        widgetIds.forEach(id => {
          const fullPath = WidgetFactory.getWidgetFullPath(id);
          fullPath.forEach(widgetId => {
            const widget = WidgetFactory.getWidgetById(widgetId);
            widget.display = true;
            const brothers = WidgetFactory.getWidgetBrothers(widget);
            brothers.forEach(brother => {
              if (WidgetFactory.judgeWidgetRectCovered(widget, brother)) {
                brother.display = false;
              }
            });
          });
        });
      },
      draggingWidget() {
        if (!this.draggingWidget) {
          // 当当前无正在拖动的组件，则重置所组件的 isHover 状态
          WidgetFactory.resetWidgetHoverStatus();
        }
      },
    },
    mounted() {
      const {rid: roomId, cid: componentId} = this.$route.params;
      this.roomId = roomId;
      this.componentId = componentId;
      document.addEventListener('keydown', this.keyboardDown);
      document.addEventListener('keyup', this.keyboardUp);
      this.$EventBus.$on('selectWidget', this.selectWidget);
      this.$EventBus.$on('widgetDrop', this.createWidget);
      this.$EventBus.$on('widgetScaling', scaling => {
        this.isWidgetScaling = scaling;
      });
    },
    beforeDestroy() {
      WidgetFactory.undoRedoHdl.clearAllOperationData();
      document.removeEventListener('keydown', this.keyboardDown);
      document.removeEventListener('keyup', this.keyboardUp);
      this.$EventBus.$off('selectWidget');
      this.$EventBus.$off('widgetDrop');
      this.$EventBus.$off('widgetScaling');
    },
    methods: {
      ...mapActions([
        'updateSelectWidgetIds',
        'updateWidgetAxis',
        'updateGlobalScenesList',
        'updateShowWidgetPage'
      ]),
      widgetAutoLayout(val) {
        this.showSelectionBox = val;
      },
      keyboardDown(event) {
        const {tagName = ''} = event.target;
        if (tagName === 'INPUT' || tagName === 'TEXTAREA') return;

        if (event.key === 'Shift') {
          event.preventDefault();
          this.isMultiSelectMode = true;
        }
        if (event.key === 'Escape') {
          event.preventDefault();
          this.showSelectionBox = false;
          this.$EventBus.$emit('selectWidget', this.pageHdl.activePage);
          this.updateShowWidgetPage(false)
        }
        if (event.key === 'Backspace' || event.key === 'Delete') {
          event.preventDefault();
          this.deleteWidget();
        }
        const ctrlActive = event.ctrlKey || event.metaKey;

        // 保存
        if (ctrlActive && ['s', 'S'].includes(event.key)) {
          event.preventDefault();
          this.$emit('save');
        }

        // 复制粘贴
        if (ctrlActive && ['c', 'C'].includes(event.key)) {
          const selection = document.getSelection();
          // 判断当前复制操作是否为文本的复制，如果是则直接返回
          if (selection.type === 'Range') return true;
          event.preventDefault();
          this.resetSelectionBoxStatus();
          this.copyWidgetHandle();
        }
        if (ctrlActive && ['v', 'V'].includes(event.key)) {
          event.preventDefault();
          this.resetSelectionBoxStatus();
          // Ctrl+Shift+V 表示使用保留子组件原有坐标，默认使用鼠标点击坐标粘贴子元素
          this.pasteWidgetHandle(event.shiftKey);
        }

        // 撤销重做
        if (ctrlActive && ['z', 'Z'].includes(event.key)) {
          event.preventDefault();
          this.undoRedoHandler(!event.shiftKey ? 'undo' : 'redo');
        }

        // 组件锁定
        if (ctrlActive && ['l', 'L'].includes(event.key)) {
          event.preventDefault();
          this.selectWidgetIds.forEach(sid => {
            const widget = WidgetFactory.getWidgetById(sid);
            WidgetFactory.updateWidgetLockStatus(widget, !widget.isLocked, event.shiftKey);
          });
        }

        // 组件创建分组
        if (ctrlActive && ['g', 'G'].includes(event.key)) {
          event.preventDefault();
          this.createGroup();
        }

        // 自定义组件编辑子组件
        if (ctrlActive && ['e', 'E'].includes(event.key)) {
          event.preventDefault();
          const isComponent = ['componentComposite', 'componentDevice'].includes(this.curWidget.type);
          if (this.editorType !== 'component' && isComponent) {
            this.curWidget.isEditing = !this.curWidget.isEditing;
            WidgetFactory.updateWidgetEditingStatus(this.curWidget, this.curWidget.isEditing);
          }
        }

        // 跳转至子页
        if (ctrlActive && ['j', 'J'].includes(event.key)) {
          event.preventDefault();
          this.$EventBus.$emit('jumpToSubPage', this.curWidget);
        }

        // 组件只允许单轴移动控制
        if (!ctrlActive) {
          event.preventDefault();
          switch (event.key) {
            case 'x':
              this.updateWidgetAxis('horizontal');
              break;
            case 'y':
              this.updateWidgetAxis('vertical');
              break;
            default:
              break;
          }
        }

        // 小组件选择器
        if (ctrlActive && ['e', 'E'].includes(event.key)) {
          event.preventDefault();
          this.updateShowWidgetPage(true)
        }

        // 组件位置微调
        if (event.key === 'ArrowUp') {
          event.preventDefault();
          this.selectWidgetIds.forEach(sid => {
            const widget = WidgetFactory.getWidgetById(sid);
            if (!widget.draggable) return;
            widget.rect.top -= 1;
          });
          this.resetSelectionBoxStatus();
        }
        if (event.key === 'ArrowDown') {
          event.preventDefault();
          this.selectWidgetIds.forEach(sid => {
            const widget = WidgetFactory.getWidgetById(sid);
            if (!widget.draggable) return;
            widget.rect.top += 1;
          });
          this.resetSelectionBoxStatus();
        }
        if (event.key === 'ArrowLeft') {
          event.preventDefault();
          this.selectWidgetIds.forEach(sid => {
            const widget = WidgetFactory.getWidgetById(sid);
            if (!widget.draggable) return;
            widget.rect.left -= 1;
          });
          this.resetSelectionBoxStatus();
        }
        if (event.key === 'ArrowRight') {
          event.preventDefault();
          this.selectWidgetIds.forEach(sid => {
            const widget = WidgetFactory.getWidgetById(sid);
            if (!widget.draggable) return;
            widget.rect.left += 1;
          });
          this.resetSelectionBoxStatus();
        }
        if (event.shiftKey && ['f', 'F'].includes(event.key)) {
          if (this.selectWidgetIds.length > 1) return
          this.citeListDialog = true
          this.handleRelateComponents()
        }
      },
      keyboardUp(event) {
        const {tagName = ''} = event.target;
        if (tagName === 'INPUT' || tagName === 'TEXTAREA') return;

        if (event.key === 'Shift') {
          this.isMultiSelectMode = false;
        }
        if (event.key === 'x' || event.key === 'y') {
          this.updateWidgetAxis('both');
        }
      },
      copyWidgetHandle() {
        const copiedWidgets = [];
        this.selectWidgetIds.forEach(id => {
          const widget = WidgetFactory.getWidgetById(id);
          // 多选的组件可能存在父子关系，这种情况需要把子组件过滤点，避免重复粘贴
          if (!this.selectWidgetIds.includes(widget.parentId)) {
            copiedWidgets.push(widget);
          }
        });
        if (!copiedWidgets.length) return;
        // 记录所拷贝子组件的框选框初始位置信息
        if (copiedWidgets.length === 1) {
          setStorage(StorageKey.originCopyBoxRect, copiedWidgets[0].rect);
        } else {
          setStorage(StorageKey.originCopyBoxRect, this.selectionBoxRect);
        }
        setStorage(StorageKey.copiedWidgets, copiedWidgets);
        messageHandle({type: 'success', msg: '组件复制成功！'});
      },
      pasteWidgetHandle(keepPosition = false) {
        // 目标组件是否 droppable
        if (!this.curWidget.droppable) {
          messageHandle({type: 'warning', msg: `选择目标组件不可粘贴创建子组件！`});
          return false;
        }
        const copiedWidgets = getStorage(StorageKey.copiedWidgets, true) || [];
        if (!copiedWidgets.length) return;
        const isMultiple = copiedWidgets.length > 1;
        let createdWidgets = []; // 记录成功被创建的组件集合
        const {
          left: boxLeft = 0, top: boxTop = 0,
          width: boxWidth = 0, height: boxHeight = 0
        } = getStorage(StorageKey.originCopyBoxRect, true);
        const {offsetX, offsetY} = this.pointerPosition;
        const addWidget = (widget) => {
          if (!widget) return;
          if (!keepPosition) {
            if (isMultiple) {
              // 多选粘贴，根据所选子组件相对于 selectionBox 的位置，以及鼠标点击的位置，计算最终子组件的坐标
              const {left: absLeft = 0, top: absTop = 0} = WidgetFactory.getWidgetAbsolutePosition(widget);
              widget.rect.left = absLeft + (offsetX - (boxLeft + boxWidth / 2));
              widget.rect.top = absTop + (offsetY - (boxTop + boxHeight / 2));
            } else {
              widget.rect.left = this.getCreatedWidgetPosition('left', widget, this.curWidget);
              widget.rect.top = this.getCreatedWidgetPosition('top', widget, this.curWidget);
            }
          }
          createdWidgets = createdWidgets.concat(WidgetFactory.widgetAppendChild(this.curWidget, widget));
        };
        copiedWidgets.forEach(widget => {
          const isSubPage = widget.type === 'subPage';
          const destWidget = !isSubPage ? widget : {...widget, children: []};
          const copiedWidget = WidgetFactory.copyWidget(destWidget);
          addWidget(copiedWidget);
          // 如果是非多选粘贴，则设置当前选中的组件为粘贴创建的组件
          !isMultiple && (this.curWidget = copiedWidget);
        });
        if (!createdWidgets.length) return;
        this.updateSelectWidgetIds(createdWidgets.map(widget => widget.id));
        this.resetSelectionBoxStatus();
        WidgetFactory.undoRedoHdl.operationHdl([{operationType: 'add', widgets: createdWidgets}]);
      },
      // 创建组件时根据鼠标点击的父组件的 offset ，计算子组件的坐标
      getCreatedWidgetPosition(type, source, dest) {
        let size;
        let pSize;
        let offset;
        const {offsetX, offsetY} = this.pointerPosition;
        switch (type) {
          case 'left':
            size = source.rect.width;
            pSize = dest.rect.width;
            offset = offsetX;
            break;
          case 'top':
            size = source.rect.height;
            pSize = dest.rect.height;
            offset = offsetY;
            break;
          default:
            break;
        }
        const halfSize = size / 2;
        if (offset - halfSize <= 0) return 0;
        if (offset + halfSize > pSize) return pSize - size;
        return offset - halfSize;
      },
      createWidget(destWidget) {
        const addWidget = (widget) => {
          if (!widget) return;
          const left = this.getCreatedWidgetPosition('left', widget, destWidget);
          const top = this.getCreatedWidgetPosition('top', widget, destWidget);
          widget.rect.left = left;
          widget.rect.top = top;
          const result = WidgetFactory.widgetAppendChild(destWidget, widget);
          if (result) {
            this.$EventBus.$emit('selectWidget', widget);
            const createdWidgets = WidgetFactory.getWidgetFlattenChildren(widget);
            if (!createdWidgets.length) return;
            WidgetFactory.undoRedoHdl.operationHdl([{operationType: 'add', widgets: createdWidgets}]);
          }
        };
        switch (this.draggingWidget.type) {
          case 'subPage':
            addWidget(WidgetFactory.copyWidget({...this.draggingWidget, children: []}));
            break;
          case 'componentComposite':
          case 'componentDevice':
            this.createCustomComponent(this.draggingWidget).then((componentPages = []) => {
              const component = componentPages.find(page => !page.isAppendage);
              const appendages = componentPages.filter(page => !!page.isAppendage);
              // 创建组件本身
              addWidget(component);
              // 创建组件附属内容
              this.createComponentAppendages(destWidget, appendages);
            });

            break;
          case 'componentFunction':
          case 'atomic':
            addWidget(this.createAtomicWidget(this.draggingWidget));
            break;
          default:
            break;
        }
      },
      createAtomicWidget(atomicWidget = {}) {
        return WidgetFactory.generateWidget({
          ...atomicWidget,
          roomId: this.roomId,
          componentId: this.componentId
        });
      },
      createCustomComponent(componentInfo = {}) {
        return new Promise(resolve => {
          this.deviceComponentId = componentInfo._id;
          if (componentInfo.devices.length > 0) {
            this.devices = componentInfo.devices
            this.$confirm(`是否自动关联设备和真值反馈?`, "提示", {
              confirmButtonText: "是",
              cancelButtonText: "否,手动关联",
              type: "warning",
              closeOnClickModal: false,
              distinguishCancelAndClose: true,
              beforeClose: (action, instance, done) => {
                if (action === 'close') { // 用户点击了关闭按钮
                  done(); // 关闭对话框
                } else if (action === 'cancel') { // 用户点击了取消按钮
                  this.relateDeviceDialog = true
                  done(); // 关闭对话框
                }else if (action === 'confirm') { // 用户点击了确定按钮
                  const param = {roomId: this.roomId, componentId: componentInfo._id, isSync: true};
                  this.applyComponent(param).then((widgets) => {
                    resolve(widgets);
                  });
                  done();
                }
              }
            }).then(() => {
            }).catch(() => {
            });
          } else {
            // 如果没有 devices，直接调用接口
            const param = {roomId: this.roomId, componentId: componentInfo._id, isSync: false};
            this.applyComponent(param).then((widgets) => {
              resolve(widgets);
            });
          }
          // 监听设备关联完成的事件
          this.$EventBus.$off('deviceRelateComplete'); // 解绑已有的监听器
          this.$EventBus.$on('deviceRelateComplete', (widget=>{
            resolve(widget);
          })); // 注册新的监听器
        });
      },
      relateDeviceSubmit(val) {
        this.newDevices = val
        const param = {
          roomId: this.roomId,
          componentId: this.deviceComponentId,
          isSync: false,
          newDevices: this.newDevices
        };
        this.applyComponent(param).then((widgets) => {
          this.relateDeviceDialog = false;
          this.$EventBus.$emit('deviceRelateComplete', widgets);
        }).catch((err) => {
          this.relateDeviceDialog = false;
        });
      },
      applyComponent(param) {
        return new Promise((resolve, reject) => {
          API.room.roomApplyComponent(param).then((resp) => {
            const widgets = resp.data || [];
            if (!widgets.length) {
              messageHandle({type: 'warning', msg: `组件配置信息为空，请先进行组件制作！`});
              return;
            }
            // 发送通知刷新全局设备列表和真值反馈规则列表
            this.$EventBus.$emit('refreshGlobalDevices');
            this.$EventBus.$emit('refreshGlobalLogicRules');
            resolve(WidgetFactory.assembleWidgetFromArray(widgets));
          }).catch((err) => {
            reject(err);
          });
        });
      },
      createComponentAppendages(destWidget, appendages = []) {
        const fullPath = WidgetFactory.getWidgetFullPath(destWidget.id);
        const parentPage = WidgetFactory.getWidgetById(fullPath[0]);
        // 对附加内容进行缩放处理，并追加到当前组件从属的页面上
        const targetRect = {width: parentPage.rect.width, height: parentPage.rect.height};
        appendages.forEach(appendage => {
          const sourceRect = {width: appendage.rect.width, height: appendage.rect.height};
          WidgetFactory.getWidgetFlattenChildren(appendage, false).forEach(child => {
            WidgetFactory.widgetScaleTransform(child, sourceRect, targetRect);
          });
          appendage.display = false;
          appendage.rect.left = 0;
          appendage.rect.top = 0;
          appendage.visible = false;
          WidgetFactory.widgetAppendChild(parentPage, appendage);
        });
      },
      deleteWidget() {
        if (!this.selectWidgetIds.length) return;
        const judgeIsTabBarContent = (widget = {}) => {
          if (!widget.parentId) return false;
          const parent = WidgetFactory.getWidgetById(widget.parentId);
          return parent && parent.category === 'tabBarPage';
        };
        const judgeIsPageViewContent = (widget = {}) => {
          if (!widget.parentId) return false;
          const parent = WidgetFactory.getWidgetById(widget.parentId);
          return parent && parent.category === 'pageView';
        };

        let deletedWidgets = []; // 记录所有被成功删除的组件集合
        this.selectWidgetIds.forEach(id => {
          const widget = WidgetFactory.getWidgetById(id);
          if (widget.isRoot) return;
          if (judgeIsTabBarContent(widget)) return;
          if (judgeIsPageViewContent(widget)) return;
          //如果是小组件详情页 不给删除 删除小组件详情页一并删除
          if(widget.appendageId.length>0) return;
          if(widget.category === 'deviceWidget') {
            const detailPage = WidgetFactory.getWidgetByAppendId( widget.id);
            detailPage.forEach(dialog => {
              WidgetFactory.deleteWidget(dialog)
            })
          }
          //如果是设备组件或者复合组件带弹框，删除则一并删除
          if(widget.type === 'componentComposite' || widget.category === 'componentDevice') {
            const dialogPage = WidgetFactory.getWidgetByDialogId(widget.id);
            dialogPage.forEach(dialog => {
              WidgetFactory.deleteWidget(dialog)
            })
          }
          const widgets = WidgetFactory.deleteWidget(widget);
          deletedWidgets = deletedWidgets.concat(widgets);
        });
        if (!deletedWidgets.length) return;
        if (this.selectWidgetIds.length === 1) {
          const widget = WidgetFactory.getWidgetById(this.selectWidgetIds[0]);
          this.$EventBus.$emit('selectWidget', WidgetFactory.getWidgetById(widget.parentId));
        } else {
          this.$EventBus.$emit('selectWidget', this.pageHdl.activePage);
        }
        this.pageHdl.refreshPageWidgetSortNo();
        this.$EventBus.$emit('deleteWidget', deletedWidgets);
        WidgetFactory.undoRedoHdl.operationHdl([{operationType: 'delete', widgets: deletedWidgets}]);
      },
      async undoRedoHandler(action) {
        let optWidgets = [];
        switch (action) {
          case 'undo':
            optWidgets = await WidgetFactory.undoRedoHdl.undo();
            break;
          case 'redo':
            optWidgets = await WidgetFactory.undoRedoHdl.redo();
            break;
          default:
            break;
        }
        if (optWidgets.length) {
          const lastWidget = optWidgets[optWidgets.length - 1];
          if (!lastWidget.isDeleted) {
            const optWidgetIds = _.map(optWidgets, 'id');
            this.updateSelectWidgetIds(optWidgetIds);
            this.curWidget = lastWidget;
            this.resetSelectionBoxStatus();
          } else {
            const parent = WidgetFactory.getWidgetById(lastWidget.parentId);
            this.updateSelectWidgetIds([parent.id]);
            this.curWidget = parent;
            this.showSelectionBox = false;
          }
          this.curPageHandler.updateActivePage(this.curWidget);
        }
        this.$EventBus.$emit('undoRedoExecute', optWidgets);

      },
      selectWidget(widget = {}) {
        this.showSelectionBox = false;
        // 主动让当前选中的输入框失焦，防止输入不触发 change 事件
        Array.from(document.getElementsByTagName('input')).forEach(input => input.blur());
        this.$nextTick(() => {
          const {id} = widget;
          let selectWidgetIds = this.selectWidgetIds;
          if (this.isMultiSelectMode) {
            if (widget.isRoot) {
              // 如果是根组件，组多只能选择一个
              selectWidgetIds = [id];
            } else {
              if (this.curWidget.isRoot) {
                // 如果当前选中的组件是根组件，则多选时先把根组件去除
                selectWidgetIds = [id];
              } else {
                if (!selectWidgetIds.includes(id)) {
                  selectWidgetIds.push(id);
                } else {
                  if (selectWidgetIds.length > 1) {
                    selectWidgetIds.splice(selectWidgetIds.indexOf(id), 1);
                  }
                }
              }
            }
            this.showSelectionBox = true;
          } else {
            selectWidgetIds = [id];
          }
          this.updateSelectWidgetIds(selectWidgetIds);
          this.curWidget = widget;
        });
      },
      // 更新选择框显示/隐藏状态，用于组件位置改变后重新创建 selectionBox
      resetSelectionBoxStatus() {
        if (this.selectWidgetIds.length < 2) return;
        this.showSelectionBox = false;
        this.$nextTick(() => {
          this.showSelectionBox = true;
        }, 100);
      },
      createGroup() {
        const widgets = this.selectWidgetIds.map(id => WidgetFactory.getWidgetById(id));
        if (widgets.length < 2) return;
        const parentIds = _.uniq(_.map(widgets, 'parentId'));
        if (parentIds.length > 1) {
          this.$message({message: '请选择同一父级下的组件添加分组!', type: 'warning', duration: 2000});
          return;
        }
        this.$prompt(`确定要添加分组吗?`, "提示", {
          inputValue: '分组',
          inputPlaceholder: '请输入分组名称',
          confirmButtonText: "确定",
          cancelButtonText: "取消",
        }).then(({value}) => {
          const destParent = WidgetFactory.getWidgetById(parentIds[0]);
          const group = WidgetFactory.widgetsAppendParent(destParent, widgets, value);
          this.$EventBus.$emit('createWidgetGroup', destParent);
          this.$EventBus.$emit('selectWidget', group);
          this.pageHdl.refreshPageWidgetSortNo();
          // const createdWidgets = WidgetFactory.getWidgetFlattenChildren(group);
          // WidgetFactory.undoRedoHdl.operationHdl([{operationType: 'add', widgets: createdWidgets}]);
        }).catch(() => {
        });
      },
      // 跳转指定关联组件
      jumpComponents(id) {
        this.$nextTick(() => {
          this.citeListDialog = false;
          const widgets = WidgetFactory.getWidgetById(id);
          if (widgets.subPageId) {
            this.$parent.curPageType = 'subPage';
            this.curSubPageHandler.updateActivePage(widgets);
          } else {
            this.$parent.curPageType = 'page';
            this.curPageHandler.updateActivePage(widgets);
          }
          this.$EventBus.$emit('selectWidget', widgets);
        });
      },
      //处理查找组件方法
      handleRelateComponents() {
        const widgets = deepCopy(WidgetFactory.production);
        const targetValue = this.curWidget.id;
        widgets.forEach((obj => {
          delete obj.children
          delete obj.parentId
        }))
        const foundObjects = widgets.filter(obj => findObjectByValue(obj, targetValue));
        const foundLogic = this.globalLogicList.filter(obj => findObjectByValue(obj, targetValue));
        const filterFoundObjects = foundObjects.filter(obj => {
          return obj.id !== targetValue && !obj.relateSubPage
        });
        //拿关联组件
        this.relatedComponents = filterFoundObjects.map(component => ({id: component.id, name: component.name}));
        //拿关联真值反馈
        this.relatedLogic = foundLogic.map(component => ({id: component._id, name: component.name}));
      },
      jumpLogic(id) {
        const items = this.globalLogicList.filter(obj => obj._id === id);
        let logicType = [
          {value: 'room', type: 'relatedSystem'},
          {value: 'device', type: 'relatedDeviceStatus'},
          {value: 'component', type: 'relatedAtomic'},
          {value: 'global', type: 'relatedGlobal'},
        ];
        const matchedObject = logicType.filter(obj1 => {
          const matchedObj2 = items.find(obj2 => obj2.type === obj1.type);
          return matchedObj2 !== undefined;
        });
        this.$emit('jumpLogic', {'activeLogic': matchedObject[0].value, 'showIftttDialog': true});
      },
      /*手动关联真值反馈*/

    },
  }
</script>

<style scoped lang="less">

  .editor-opt-header {
    height: 50px;
    background: @colorWhite;
    border-bottom: 1px solid #DADCE5;
    z-index: 999;
  }

  .editor-workspace {
    position: relative;
    height: calc(100vh - 90px);
    overflow: auto;
    background: url("../../../assets/img/canvas_bg.jpeg") repeat;

    .pad-window {
      position: absolute;
      top: 20px;
      left: 20px;
      transform-origin: left top;
    }

    .editor-slider {
      position: fixed;
      top: 250px;
      right: 5px;
      width: 60px;
      z-index: 999;
    }
  }

  .editor-attribute-side {
    position: relative;
    border-left: 1px solid #DADCE5;

    .side-collapse-icon {
      position: absolute;
      left: -30px;
      top: 12px;
      cursor: pointer;
      z-index: 999;

      &:hover {
        color: @colorPrimary;
      }
    }
  }

  .slider-block {
    position: fixed;
    bottom: 20px;
    right: 310px;

    /deep/ .el-slider__bar {
      background: #bbb;
    }

    /deep/ .el-slider__button {
      border: solid 2px #bbb;
    }
  }
</style>
